from flask import Flask, request, jsonify, send_file
from flask_cors import CORS
import requests
import json
import os
import tempfile
import docx2txt
import PyPDF2
from io import BytesIO
from docx import Document
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
import re
from openai import OpenAI
import traceback

app = Flask(__name__)
CORS(app)

# 创建上传文件的临时目录
UPLOAD_FOLDER = tempfile.mkdtemp()
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 限制上传文件大小为16MB

BASE_URL = "https://api.hunyuan.cloud.tencent.com/v1"
API_KEY = "sk-WeCS6vA3jK5fFgkIbLMmqk2J5U3HdWAPTSVbr79qnwJ88Tvn"  # 替换为您的API密钥

# 创建OpenAI客户端
client = OpenAI(
    api_key=API_KEY,
    base_url=BASE_URL,
)

def call_large_model(text):
    style = request.json.get('style', '')
    domain = request.json.get('domain', '')
    text_style = request.json.get('textStyle', '')
    
    # 打印整个请求以便调试
    print(f"完整请求体: {request.json}")
    print(f"【文体类型调试】文体类型: {text_style}, 类型: {type(text_style).__name__}")
    
    # 文体类型规范化处理
    valid_text_styles = ["general", "academic", "narrative", "formal", 
                         "creative", "news", "technical", "speech", "blog"]
    
    # 检查并规范化文体类型
    if text_style:
        text_style = text_style.lower().strip()
        # 打印所有请求参数，用于调试
        print(f"原始请求参数 - text_style: '{text_style}', domain: '{domain}', style: '{style}'")
        print(f"请求内容: {request.json}")
        
        if text_style not in valid_text_styles:
            closest_match = find_closest_style(text_style, valid_text_styles)
            print(f"警告: 无效的文体类型 '{text_style}'，尝试匹配到: '{closest_match}'")
            text_style = closest_match
    
    print(f"处理文体类型: '{text_style}'")
    
    print(f"收到润色请求 - 文体类型: {text_style}, 领域: {domain}, 风格: {style}")
    
    # 检测原文可能的文体类型，以便更好地进行转换
    original_style = detect_original_style(text)
    print(f"检测到原文文体类型: {original_style}")
    
    style_guide = f"按照以下风格进行润色：{style}。" if style else ""
    domain_guide = ""
    text_style_guide = ""
    conversion_guide = ""
    
    if domain:
        domain_mapping = {
            "medical": "医学",
            "legal": "法律",
            "tech": "技术",
            "academic": "学术",
            "business": "商业", 
            "science": "科学",
            "engineering": "工程",
            "education": "教育",
            "art": "艺术",
            "finance": "金融"
        }
        
        domain_name = domain_mapping.get(domain, domain)
        domain_guide = f"这是一篇{domain_name}领域的文本，请确保使用该领域的专业术语和规范，保持专业性和准确性。"
        
        # 为特定领域添加专门指导
        if domain == "medical":
            domain_guide += "使用适当的医学术语，但同时确保解释专业术语，使非专业人士也能理解。如果涉及药品，需包含功效、适应症、用法用量、注意事项等关键信息。"
    
    # 文体风格映射
    text_style_mapping = {
        "general": "通用",
        "academic": "学术论文",
        "narrative": "叙事文学",
        "formal": "正式文件",
        "creative": "创意写作",
        "news": "新闻报道",
        "technical": "技术文档",
        "speech": "演讲稿",
        "blog": "博客文章"
    }
    
    # 如果检测到原文风格与目标风格不同，添加转换指导
    if original_style and text_style and original_style != text_style:
        conversion_guide = f"""
重要：这是一篇{text_style_mapping.get(original_style, original_style)}，需要将其完全转换为{text_style_mapping.get(text_style, text_style)}格式。
请保留原始内容的核心信息和关键点，但彻底重构文本结构和表达方式，使其完全符合{text_style_mapping.get(text_style, text_style)}的风格和特点。
"""
    
    # 添加不同文体的具体指导
    if text_style == "general" or not text_style:
        text_style_guide = "请对文本进行基础润色，提高表达的流畅性和准确性。"
    elif text_style == "academic":
        text_style_guide = """请按照学术论文的文体风格进行润色或转换，必须包含以下特点：
1. 使用学术规范的表达方式和学术术语
2. 保持严谨的逻辑结构，清晰的论点-论据-论证过程
3. 添加适当的学术引用格式和参考文献标注
4. 使用客观、中立的语气
5. 如果原文不是学术论文，请完全重构为学术论文格式，包括摘要、引言、方法、结果、讨论和结论等部分
"""
    elif text_style == "narrative":
        text_style_guide = """请按照叙事文学的文体风格进行润色或转换，必须包含以下特点：
1. 增强故事性和画面感，使用生动的描写
2. 发展清晰的人物、情节和场景
3. 使用适当的修辞手法，如比喻、拟人等
4. 丰富情节和人物刻画，注重情感表达
5. 如果原文不是叙事文体，请将其转换为故事形式，添加情节、人物对话和场景描写
"""
    elif text_style == "formal":
        text_style_guide = """请按照正式文件的文体风格进行润色或转换，必须包含以下特点：
1. 使用庄重、规范的语言，避免口语化表达
2. 保持客观和中立的语气
3. 采用标准化的表达结构和格式
4. 确保表述的严谨性和准确性
5. 如果原文不是正式文件，请重构为正式文件格式，包括适当的标题、编号和分段
"""
    elif text_style == "creative":
        text_style_guide = """请按照创意写作的文体风格进行润色或转换，必须包含以下特点：
1. 增加创意性和新颖性，使用独特的表达方式
2. 运用丰富的修辞手法，如夸张、对比、排比等
3. 打破常规思维，展现想象力和艺术性
4. 如果原文不是创意文体，请完全重构内容，保留核心信息但以创意的方式表达
"""
    elif text_style == "news":
        text_style_guide = """请按照新闻报道的文体风格进行润色或转换，必须包含以下特点：
1. 采用倒金字塔结构，最重要的信息放在开头
2. 包含5W1H要素（何人、何事、何时、何地、为何、如何）
3. 使用客观、简洁的表达方式，避免主观评价
4. 如果原文不是新闻报道，请将其转换为新闻格式，添加标题、导语和正文
5. 保持事实准确和报道中立
"""
    elif text_style == "technical":
        text_style_guide = """请按照技术文档的文体风格进行润色或转换，必须包含以下特点：
1. 使用专业、精确的术语和定义
2. 保持结构清晰和逻辑性，可使用编号或项目符号列表
3. 采用直接、简洁的说明方式
4. 如果原文不是技术文档，请重构为技术规范或说明书格式
5. 可添加适当的图表描述、步骤说明或参数列表
"""
    elif text_style == "speech":
        text_style_guide = """请将文本彻底转化为适合演讲的稿件格式，必须包含以下特点：
1. 添加引人入胜的开场白，包括问候语和自我介绍
2. 明确演讲的主题和目的
3. 正文部分组织为清晰的几个要点，每个要点有论述和例证
4. 大量使用口语化表达，增加亲切感和互动性
5. 添加修辞问句和互动元素（如"大家有没有想过..."）
6. 使用大量过渡衔接词，确保内容流畅衔接
7. 如果是医学领域，添加具体病例分析或研究数据
8. 如果是产品介绍，加入产品优势和用户反馈
9. 添加有力的结束语和号召性用语
10. 如果原文是说明书或技术文档，请完全重构为以人为中心的演讲形式
"""
    elif text_style == "blog":
        text_style_guide = """请按照博客文章的文体风格进行润色或转换，必须包含以下特点：
1. 使用个性化的表达方式，展现作者的独特视角
2. 增加与读者的互动元素，如设问、邀请评论等
3. 保持亲切自然的语气，使用第一人称
4. 适当使用网络用语和时尚表达
5. 如果原文不是博客风格，请重构为博客文章，添加吸引人的标题、个人观点和读者互动元素
"""
    else:
        style_name = text_style_mapping.get(text_style, text_style)
        text_style_guide = f"请按照{style_name}的文体风格进行润色，确保符合此类型文章的表达方式和结构。"
    
    prompt = f"""请分析并{conversion_guide if conversion_guide else '润色'}以下文本。{style_guide} {domain_guide} {text_style_guide}返回的结果需要严格按照以下规则使用HTML标记：

1. 使用以下三种标记来显示不同类型的修改：
   - 完全删除的内容：使用 <del>删除的文字</del>
   - 完全新增的内容：使用 <span style="color: blue;">新增的文字</span>
   - 在原有内容基础上改动（如改写、调整语序）：使用 <span style="background-color: #90EE90;">改动后的文字</span>

2. 标记使用规则：
   - 当完全删除一段文字时，使用 del 标签
   - 当添加全新的内容时，使用蓝色文字
   - 当对原文进行改写、调整语序时，使用绿色背景
   - 每处修改必须使用以上三种标记之一，不能有未标记的修改

3. 保持原文的核心意思和关键信息
4. 直接返回带标记的修改后文本，不要包含任何解释
"""

    # 为通用文体和特定文体添加不同指导
    if text_style == "general" or not text_style:
        prompt += """
5. 执行基础润色，提高表达的流畅性、准确性和语言质量。
"""
    else:
        prompt += """
5. 除了基础润色外，请按照指定的文体风格彻底改造文本，添加该文体特有的结构和表达特点。具体要求：
   - 如果文体需要特定开场白和结束语，请添加
   - 如果文体需要特定的语气词和衔接词，请适当添加
   - 如果文体有特定的结构要求，请按照该结构调整内容
   - 保证语言风格完全符合该文体的特点
   - 如果原文文体与目标文体差异很大，允许大幅重构内容，但保留核心信息
"""

    # 为特定文体和领域组合提供具体示例
    if text_style == "speech" and domain == "medical":
        prompt += """
特别说明：
如果原文是药品说明书或医学指南，请将其转换为一篇关于该药品或医疗方法的演讲稿，包括：
1. 开场白：问候听众并介绍演讲主题
2. 引言：简要介绍该药品/方法的背景和意义
3. 主体：
   - 详细介绍药品/方法的功效和作用机理
   - 分享2-3个成功的临床案例或研究数据
   - 讨论使用注意事项和最佳实践
4. 结束语：总结主要观点并感谢听众

示例开场白：
"尊敬的各位医学同行，亲爱的健康工作者们，大家上午好！今天我非常荣幸能与大家分享关于[药品名称]的最新研究成果和临床应用经验..."

示例临床案例引入：
"让我们来看一个真实的病例。去年，一位58岁的张先生因长期[症状]来到我们医院..."

示例结束语：
"综上所述，[药品名称]在[适应症]治疗中展现出了显著的临床价值。我相信随着我们的深入研究和临床实践，将能帮助更多患者重获健康。感谢大家的聆听，如有任何问题，我非常乐意在之后的讨论环节一一解答。谢谢大家！"
"""

    # 特别强调需要进行文体转换
    if text_style and text_style != "general":
        prompt += f"""
最重要的指导：这是一个文体转换任务。你必须将输入文本完全转换为{text_style_mapping.get(text_style, text_style)}的格式和风格，而不仅仅是润色。生成的内容应该明显地具有{text_style_mapping.get(text_style, text_style)}的特点，使任何人一眼就能识别这是一篇{text_style_mapping.get(text_style, text_style)}。
"""

    prompt += f"""
需要润色的文本：
{text}"""

    print("生成的提示:")
    print(prompt[:500] + "..." if len(prompt) > 500 else prompt)  # 只打印前500字符

    try:
        # 使用OpenAI客户端调用API
        print(f"调用模型API - 模型: hunyuan-turbos-latest, 文体: {text_style}")
        
        # 记录最终传递给模型的完整提示
        print(f"提示前500字符: {prompt[:500]}...")
        
        messages_to_send = [
            {
                "role": "user",
                "content": prompt
            }
        ]
        
        # 如果是有特定文体要求，添加系统消息强调文体转换
        if text_style and text_style != "general":
            style_name = text_style_mapping.get(text_style, text_style)
            system_message = f"请注意这是一个文体转换任务，你必须将文本转换为{style_name}格式，而不只是简单润色。"
            messages_to_send.insert(0, {"role": "system", "content": system_message})
            print(f"添加系统消息: {system_message}")
        
        completion = client.chat.completions.create(
            model="hunyuan-turbos-latest",  # 使用混元最新模型
            messages=messages_to_send,
            temperature=0.7 if text_style not in ["speech", "creative", "narrative"] else 0.85,
            max_tokens=3000,
            extra_body={
                "enable_enhancement": True,  # 启用增强特性
            },
        )
        
        # 获取响应内容
        modified_text = completion.choices[0].message.content
        print(f"API响应成功，生成文本长度: {len(modified_text)}")
        
        # 检查是否包含HTML标记，如果没有可能表示处理不正确
        if "<span" not in modified_text and "<del" not in modified_text:
            print("警告: 生成的文本中没有HTML标记，可能没有正确处理")
        
        # 如果是演讲稿，进行特殊后处理和再次调用
        if text_style == "speech":
            print("执行演讲稿特殊处理")
            # 先进行基本的后处理
            modified_text = ensure_speech_format(modified_text, text)
            
            # 如果模型生成的文本没有明显的演讲稿特征，进行二次调用
            speech_features = has_speech_features(modified_text)
            if not speech_features:
                print(f"演讲稿风格不明显，进行二次调用... 特征检测结果: {speech_features}")
                modified_text = call_speech_transformation(text, modified_text, domain)
            else:
                print(f"演讲稿特征检测通过，特征分数: {speech_features}")
            
        return modified_text
    except Exception as e:
        print(f"详细错误: {str(e)}")
        traceback_info = traceback.format_exc()
        print(f"完整错误追踪: {traceback_info}")
        return f"调用 API 时出错: {str(e)}"

def detect_original_style(text):
    """尝试检测原始文本的文体类型"""
    # 药品说明书特征
    if any(keyword in text for keyword in ['适应症', '用法用量', '不良反应', '禁忌', '注意事项', '有效期', '规格', '贮藏']):
        return "technical"  # 技术文档
    
    # 学术论文特征
    if any(keyword in text for keyword in ['摘要', '关键词', '引言', '方法', '结果', '讨论', '结论', '参考文献']):
        return "academic"
    
    # 新闻报道特征
    if re.search(r'\d+月\d+日', text) and ('报道' in text or '消息' in text):
        return "news"
    
    # 叙事文学特征
    if '小说' in text or '故事' in text or re.search(r'第.{1,3}章', text):
        return "narrative"
    
    # 博客文章特征
    if '我认为' in text or '我觉得' in text or '我的看法' in text:
        return "blog"
    
    # 演讲稿特征
    if '大家好' in text or '谢谢大家' in text or '各位' in text:
        return "speech"
    
    # 默认返回通用或空
    return ""

def ensure_speech_format(modified_text, original_text):
    """确保演讲稿格式正确，如果没有开场白或结束语则添加"""
    # 清理版本用于检测开场白和结束语
    clean_text = modified_text.replace('<del>', '').replace('</del>', '')
    clean_text = clean_text.replace('<span style="color: blue;">', '').replace('</span>', '')
    clean_text = clean_text.replace('<span style="background-color: #90EE90;">', '').replace('</span>', '')
    
    # 检查是否已有开场白（通常在开头几行）
    has_opening = False
    first_few_lines = clean_text.split('\n')[:3]
    opening_keywords = ['大家好', '各位', '朋友们', '女士们先生们', '尊敬的', '亲爱的', '很高兴', '荣幸']
    for line in first_few_lines:
        if any(keyword in line for keyword in opening_keywords):
            has_opening = True
            break
    
    # 检查是否已有结束语（通常在最后几行）
    has_closing = False
    last_few_lines = clean_text.split('\n')[-3:]
    closing_keywords = ['谢谢', '感谢', '致谢', '再见', '共同努力', '期待', '未来', '最后', '结束']
    for line in last_few_lines:
        if any(keyword in line for keyword in closing_keywords):
            has_closing = True
            break
    
    # 如果缺少开场白，添加一个
    if not has_opening:
        # 尝试从原文中提取主题
        topic = extract_topic(original_text)
        opening = f'<span style="color: blue;">尊敬的各位来宾，亲爱的朋友们，大家好！\n\n今天我很荣幸能与大家分享关于{topic}的一些想法。</span>\n\n'
        modified_text = opening + modified_text
    
    # 如果缺少结束语，添加一个
    if not has_closing:
        closing = f'\n\n<span style="color: blue;">最后，感谢大家的聆听！让我们一起为实现这个目标而共同努力！谢谢大家！</span>'
        modified_text += closing
    
    # 添加更多口语化表达和互动元素
    paragraphs = modified_text.split('\n\n')
    enhanced_paragraphs = []
    
    speech_enhancements = [
        '<span style="color: blue;">朋友们，</span> ',
        '<span style="color: blue;">大家想一想，</span> ',
        '<span style="color: blue;">让我们来看看，</span> ',
        '<span style="color: blue;">我想强调的是，</span> ',
        '<span style="color: blue;">值得注意的是，</span> ',
        '<span style="color: blue;">你们知道吗？</span> ',
        '<span style="color: blue;">我们可以看到，</span> ',
        '<span style="color: blue;">接下来，</span> ',
        '<span style="color: blue;">此外，</span> ',
        '<span style="color: blue;">那么，</span> '
    ]
    
    # 只增强一部分段落，避免过度修改
    enhancement_count = 0
    max_enhancements = min(len(paragraphs) // 2, 5)  # 最多增强5段或一半段落
    
    for i, para in enumerate(paragraphs):
        # 跳过已经有开场白或结束语的段落
        if i == 0 and has_opening or i == len(paragraphs) - 1 and has_closing:
            enhanced_paragraphs.append(para)
            continue
            
        # 只为一部分段落添加演讲元素
        if enhancement_count < max_enhancements and len(para) > 30 and '<span style="color: blue;">' not in para[:30]:
            # 随机选择一个演讲增强元素
            import random
            enhancement = random.choice(speech_enhancements)
            enhanced_para = enhancement + para
            enhanced_paragraphs.append(enhanced_para)
            enhancement_count += 1
        else:
            enhanced_paragraphs.append(para)
    
    return '\n\n'.join(enhanced_paragraphs)

def extract_topic(text):
    """从原文中提取可能的主题"""
    # 简单实现：取前30个字符，找到第一个标点符号前的内容作为主题
    # 真实场景可以使用更复杂的NLP方法
    preview = text[:100]
    for i, char in enumerate(preview):
        if char in '，。！？；：,.!?;:':
            return preview[:i]
    
    # 如果没找到标点，取前10个字
    topic_text = text[:10] if len(text) > 10 else text
    return topic_text + "相关内容"

def extract_text_from_file(file):
    filename = file.filename
    file_ext = os.path.splitext(filename)[1].lower()
    
    if file_ext == '.txt':
        # 处理 TXT 文件
        content = file.read().decode('utf-8')
        return content
    
    elif file_ext in ['.docx', '.doc']:
        # 处理 Word 文件
        try:
            content = docx2txt.process(file)
            return content
        except Exception as e:
            print(f"处理 Word 文件时出错: {str(e)}")
            return f"处理 Word 文件时出错: {str(e)}"
    
    elif file_ext == '.pdf':
        # 处理 PDF 文件
        try:
            pdf_reader = PyPDF2.PdfReader(file)
            text = ""
            for page in pdf_reader.pages:
                text += page.extract_text() + "\n"
            return text
        except Exception as e:
            print(f"处理 PDF 文件时出错: {str(e)}")
            return f"处理 PDF 文件时出错: {str(e)}"
    
    else:
        return f"不支持的文件格式: {file_ext}"

def create_docx_from_text(text, output_filename):
    doc = Document()
    # 移除HTML标签
    clean_text = text.replace('<del>', '').replace('</del>', '')
    clean_text = clean_text.replace('<span style="color: blue;">', '').replace('</span>', '')
    clean_text = clean_text.replace('<span style="background-color: #90EE90;">', '').replace('</span>', '')
    
    # 添加到文档
    paragraphs = clean_text.split('\n')
    for para in paragraphs:
        if para.strip():
            doc.add_paragraph(para)
    
    # 保存文档
    output_path = os.path.join(app.config['UPLOAD_FOLDER'], output_filename)
    doc.save(output_path)
    return output_path

def create_pdf_from_text(text, output_filename):
    output_path = os.path.join(app.config['UPLOAD_FOLDER'], output_filename)
    
    # 创建PDF文件
    c = canvas.Canvas(output_path, pagesize=letter)
    width, height = letter
    
    # 尝试注册中文字体
    font_name = 'Helvetica'
    try:
        # 尝试加载中文字体
        font_path = None
        
        # 常见中文字体路径
        possible_font_paths = [
            '/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf',  # Linux
            '/usr/share/fonts/truetype/wqy/wqy-microhei.ttc',  # Linux
            '/Library/Fonts/Arial Unicode.ttf',  # macOS
            'C:\\Windows\\Fonts\\simkai.ttf',  # Windows
            'C:\\Windows\\Fonts\\simhei.ttf',  # Windows
            'C:\\Windows\\Fonts\\simsun.ttc',  # Windows
            'C:\\Windows\\Fonts\\msyh.ttc',  # Windows
        ]
        
        for path in possible_font_paths:
            if os.path.exists(path):
                font_path = path
                break
                
        if font_path:
            font_name = os.path.basename(font_path).split('.')[0]
            pdfmetrics.registerFont(TTFont(font_name, font_path))
        
    except Exception as e:
        print(f"注册字体失败: {str(e)}")
    
    # 移除HTML标签
    clean_text = text.replace('<del>', '').replace('</del>', '')
    clean_text = clean_text.replace('<span style="color: blue;">', '').replace('</span>', '')
    clean_text = clean_text.replace('<span style="background-color: #90EE90;">', '').replace('</span>', '')
    
    # 将文本分成段落
    paragraphs = clean_text.split('\n')
    
    # 设置字体和大小
    c.setFont(font_name, 12)
    
    # 添加文本到PDF
    y_position = height - 50
    line_height = 15
    
    for para in paragraphs:
        if not para.strip():
            y_position -= line_height / 2
            continue
        
        # 中文文本处理 - 按字符分割而不是按空格分词
        if any('\u4e00' <= char <= '\u9fff' for char in para):  # 检查是否包含中文字符
            # 中文文本处理
            current_line = ""
            for char in para:
                test_line = current_line + char
                # 检查加上这个字符后是否会超出宽度
                if c.stringWidth(test_line, font_name, 12) < width - 100:
                    current_line = test_line
                else:
                    # 写入当前行并开始新行
                    c.drawString(50, y_position, current_line)
                    y_position -= line_height
                    current_line = char
                    
                    # 检查是否需要新页
                    if y_position < 50:
                        c.showPage()
                        c.setFont(font_name, 12)
                        y_position = height - 50
            
            # 写入最后一行
            if current_line:
                c.drawString(50, y_position, current_line)
                y_position -= line_height * 1.5
        else:
            # 英文文本处理 - 按空格分词
            words = para.split()
            line = ""
            for word in words:
                test_line = line + " " + word if line else word
                # 检查是否需要换行
                if c.stringWidth(test_line, font_name, 12) < width - 100:
                    line = test_line
                else:
                    c.drawString(50, y_position, line)
                    y_position -= line_height
                    line = word
                    
                    # 检查是否需要新页
                    if y_position < 50:
                        c.showPage()
                        c.setFont(font_name, 12)
                        y_position = height - 50
            
            # 写入最后一行
            if line:
                c.drawString(50, y_position, line)
                y_position -= line_height * 1.5
        
        # 检查段落结束后是否需要新页
        if y_position < 50:
            c.showPage()
            c.setFont(font_name, 12)
            y_position = height - 50
    
    c.save()
    return output_path

@app.route('/')
def home():
    return send_file('index.html')

@app.route('/polish', methods=['POST'])
def polish_text():
    try:
        original_text = request.json.get('text', '')
        if not original_text:
            return jsonify({"error": "请输入文本"}), 400
        
        # 检查文本长度，避免处理过长文本
        if len(original_text) > 10000:  # 限制处理10000字以内的文本
            return jsonify({"error": "文本过长，请控制在10000字以内"}), 400
        
        # 获取并验证文体类型
        text_style = request.json.get('textStyle', '')
        domain = request.json.get('domain', '')
        
        # 打印原始请求数据，帮助诊断问题
        print(f"润色请求原始数据: {request.json}")
        print(f"处理润色请求 - 文本长度: {len(original_text)}, 文体类型: '{text_style}', 领域: '{domain}'")
        
        # 对不同文体类型使用不同的处理逻辑
        if 'speech' in text_style.lower():
            print("检测到演讲稿文体类型，设置为speech")
            text_style = 'speech'
        
        modified_text = call_large_model(original_text)
        
        # 添加文体信息到返回
        response_data = {
            "modified_text": modified_text,
            "text_style": text_style,
            "domain": domain,
            "processed_text_style": text_style  # 添加实际处理的文体类型
        }
        
        # 如果文体是演讲稿，添加提示信息
        if text_style == "speech":
            response_data["note"] = "已将文本转换为演讲稿格式，添加了开场白、结束语和口语化表达。"
        
        print(f"润色完成 - 文体类型: '{text_style}', 响应长度: {len(modified_text)}")
        return jsonify(response_data)
    except Exception as e:
        error_msg = str(e)
        print(f"润色失败: {error_msg}")
        import traceback
        traceback_info = traceback.format_exc()
        print(f"完整错误追踪: {traceback_info}")
        # 返回更详细的错误信息
        return jsonify({
            "error": error_msg,
            "details": "请检查文体类型和其他参数是否正确",
            "received_params": {
                "text_style": request.json.get('textStyle', ''),
                "domain": request.json.get('domain', ''),
                "style": request.json.get('style', '')
            }
        }), 500

@app.route('/upload-file', methods=['POST'])
def upload_file():
    try:
        if 'file' not in request.files:
            return jsonify({"error": "没有文件"}), 400
            
        file = request.files['file']
        if file.filename == '':
            return jsonify({"error": "没有选择文件"}), 400
            
        # 安全地获取文件名
        filename = os.path.basename(file.filename)
        
        # 提取文件内容
        content = extract_text_from_file(file)
        
        return jsonify({
            "filename": filename,
            "content": content,
            "message": "上传成功"
        })
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/export', methods=['POST'])
def export_file():
    try:
        text = request.json.get('text', '')
        format = request.json.get('format', 'docx')
        original_filename = request.json.get('filename', 'document')
        
        # 去掉原始文件名的扩展名
        basename = os.path.splitext(original_filename)[0]
        
        if format == 'docx':
            output_filename = f"{basename}_润色后.docx"
            output_path = create_docx_from_text(text, output_filename)
            mimetype = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
        elif format == 'pdf':
            output_filename = f"{basename}_润色后.pdf"
            output_path = create_pdf_from_text(text, output_filename)
            mimetype = 'application/pdf'
        elif format == 'txt':
            output_filename = f"{basename}_润色后.txt"
            
            # 移除HTML标签
            clean_text = text.replace('<del>', '').replace('</del>', '')
            clean_text = clean_text.replace('<span style="color: blue;">', '').replace('</span>', '')
            clean_text = clean_text.replace('<span style="background-color: #90EE90;">', '').replace('</span>', '')
            
            output_path = os.path.join(app.config['UPLOAD_FOLDER'], output_filename)
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(clean_text)
            mimetype = 'text/plain'
        else:
            return jsonify({"error": "不支持的导出格式"}), 400
        
        return send_file(
            output_path,
            mimetype=mimetype,
            as_attachment=True,
            download_name=output_filename
        )
    except Exception as e:
        return jsonify({"error": str(e)}), 500

def has_speech_features(text):
    """检查文本是否具有明显的演讲稿特征"""
    # 清理HTML标签
    clean_text = text.replace('<del>', '').replace('</del>', '')
    clean_text = clean_text.replace('<span style="color: blue;">', '').replace('</span>', '')
    clean_text = clean_text.replace('<span style="background-color: #90EE90;">', '').replace('</span>', '')
    
    # 检查开场白
    first_few_lines = clean_text.split('\n')[:3]
    opening_keywords = ['大家好', '各位', '朋友们', '女士们先生们', '尊敬的', '亲爱的', '很高兴', '荣幸']
    has_opening = any(any(keyword in line for keyword in opening_keywords) for line in first_few_lines)
    
    # 检查结束语
    last_few_lines = clean_text.split('\n')[-3:]
    closing_keywords = ['谢谢', '感谢', '致谢', '再见', '共同努力', '期待', '未来', '最后', '结束']
    has_closing = any(any(keyword in line for keyword in closing_keywords) for line in last_few_lines)
    
    # 检查互动元素
    interaction_keywords = ['朋友们', '大家想一想', '让我们', '你们知道吗', '大家可以', '我想说的是']
    has_interaction = any(keyword in clean_text for keyword in interaction_keywords)
    
    # 检查衔接词
    transition_keywords = ['接下来', '此外', '那么', '因此', '所以', '最后', '首先', '第二', '另外']
    has_transition = sum(1 for keyword in transition_keywords if keyword in clean_text) >= 2
    
    # 如果具备至少三个特征，认为是演讲稿
    features_count = sum([has_opening, has_closing, has_interaction, has_transition])
    
    # 记录详细的特征检测结果
    print(f"演讲稿特征检测 - 开场白: {has_opening}, 结束语: {has_closing}, 互动元素: {has_interaction}, 衔接词: {has_transition}, 总分: {features_count}")
    
    return features_count >= 3

def call_speech_transformation(original_text, first_attempt=None, domain=None):
    """专门针对演讲稿的二次调用，直接转换为演讲稿格式"""
    # 尝试提取主题
    topic = extract_topic(original_text)
    
    # 构建更强的演讲稿转换提示
    prompt = f"""请将以下文本彻底转换为一篇正式的演讲稿格式。必须包含以下所有元素：

1. 开场白：添加"尊敬的各位来宾，亲爱的朋友们"等开场问候语
2. 明确的演讲主题介绍
3. 正文部分：使用大量的口语化表达、互动元素和修辞手法
4. 衔接词：使用"首先"、"其次"、"接下来"、"此外"、"最后"等
5. 互动元素：添加"大家想一想"、"让我们一起"、"你们知道吗"等
6. 强有力的结束语和感谢语

返回的结果需要严格按照以下规则使用HTML标记：
- 完全删除的内容：使用 <del>删除的文字</del>
- 完全新增的内容：使用 <span style="color: blue;">新增的文字</span>
- 在原有内容基础上改动：使用 <span style="background-color: #90EE90;">改动后的文字</span>
"""

    # 针对医学领域的特殊处理
    if domain == "medical":
        prompt += """
如果文本涉及药品或医疗方法，请特别添加以下内容：
1. 在开场白中介绍自己的医学背景或身份
2. 在正文中添加2-3个具体的临床案例或研究数据
3. 解释专业术语，使非专业人士也能理解
4. 讨论该药品或方法的优势、局限性和未来发展
"""

    prompt += f"""
转换为演讲稿的文本：
{original_text}"""

    try:
        # 使用OpenAI客户端调用API进行二次处理
        completion = client.chat.completions.create(
            model="hunyuan-turbos-latest",
            messages=[
                {
                    "role": "user",
                    "content": prompt
                }
            ],
            temperature=0.85,
            max_tokens=3000,
            extra_body={
                "enable_enhancement": True,  # 启用增强特性
            },
        )
        
        # 获取响应内容
        response_text = completion.choices[0].message.content
        print("演讲稿二次调用结果获取成功")
        return response_text
    except Exception as e:
        print(f"演讲稿二次调用错误: {str(e)}")
        # 出错时返回第一次的结果
        return first_attempt if first_attempt else original_text

def find_closest_style(input_style, valid_styles):
    """找到最接近的有效文体类型"""
    # 简单字符串匹配
    for style in valid_styles:
        if style in input_style or input_style in style:
            return style
    
    # 默认返回通用类型
    return "general"

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)